package salary

import (
	"math"
	"time"
)

// 支付调度
type PaymentSchedule interface {
	IsPayDay(date string) bool
	GetStartPayDate(payDate string) time.Time
}

// 月薪
type MonthlySchedule struct {
	PaymentSchedule
}

func (m *MonthlySchedule) IsPayDay(date string) bool {
	dateTime := Str2Date(date)
	now := time.Now()
	currentYear, currentMonth, _ := now.Date()
	currentLocation := now.Location()
	firstOfMonth := time.Date(currentYear, currentMonth, 1, 0, 0, 0, 0, currentLocation)
	lastOfMonth := firstOfMonth.AddDate(0, 1, -1)
	return dateTime.Day() == lastOfMonth.Day()
}

func (m *MonthlySchedule) GetStartPayDate(payDate string) time.Time {
	payDateTime := Str2Date(payDate)
	currentLocation := payDateTime.Location()
	currentYear, currentMonth, _ := payDateTime.Date()
	firstOfMonth := time.Date(currentYear, currentMonth, 1, 0, 0, 0, 0, currentLocation)
	return firstOfMonth
}

// 周薪
type WeeklySchedule struct {
	PaymentSchedule
}

func (w*WeeklySchedule) IsPayDay(date string) bool {
	// 周五发薪
	dateTime := Str2Date(date)
	return dateTime.Weekday() == time.Friday
}

func (w*WeeklySchedule) GetStartPayDate(payDate string) time.Time {
	dateTime := Str2Date(payDate)
	// 减去六天
	return dateTime.AddDate(0, 0, -6)
}

// 双周发薪
type BiWeeklySchedule struct {
	PaymentSchedule
}

func (b *BiWeeklySchedule) IsPayDay(date string) bool {
	// 周五发薪 第二周发薪
	dateTime := Str2Date(date)
	weekday := dateTime.Weekday()
	day := dateTime.Day()
	weekOfMonth := int(math.Ceil(float64(day) / 7.0))
	return weekday == time.Friday && weekOfMonth%2 == 0
}

func (b *BiWeeklySchedule) GetStartPayDate(payDate string) time.Time {
	dateTime := Str2Date(payDate)
	// 减去十三天
	return dateTime.AddDate(0, 0, -13)
}
